import React, { useState, useMemo, useEffect } from 'react';
import { cline, Ret, Title, useHigh, GridTable, useCmd, WaitUmd, MainView, KFind, useKForm, obj_str, PanelTitle,
     to_float, ck_empty, d_sort, save_xlsx, obj_int, obj_str_trim, uDb, Btn, is_empty, loc } from 'sui';
import { get_col, load_ball } from './cmd';

const Census = ({ mod, data, title, hreturn, col, map_ng, map_stuff, map_supply }) => {
    const [lst_ball, lstBall] = useState();
    const [row, setRow] = useState();
    const [sum, setSum] = useState([]);
    const [high] = useHigh(220, 100);
    const umd = useCmd();
    const form = useKForm();

    useEffect(() => load_ball(lstBall), []);

    const techList = useMemo(() => {
        if (is_empty(data)) {
            return null;
        }

        const set = new Set();
        const ret = [];

        data.forEach(d => {
            const tech = obj_str_trim(d, "sn");
            if (set.has(tech)) {
                return;
            }

            ret.push({ sn: "" + tech, name: tech });
            set.add(tech);
        });

        d_sort(ret, "sn");

        return ret;
    }, [data]);

    const hfind = () => {
        const ck = {
            tech : v => ck_empty(v),
            ball : v => ck_empty(v),
        };

        if (form.isErr(ck)) {
            return;
        }

        const tech = form.get("tech");
        const ball = "" + to_float(form.get("ball"));

        umd.startWait();

        const calc = (test, ok, stock) => {
            let dnum_test = 0;
            let dnum_test_open = 0;
            let dnum_test_run = 0;
            let dnum_test_close = 0;
            let dnum_ok = 0;
            let dnum_stock = 0;

            let dnum_test_a = 0;
            let dnum_test_open_a = 0;
            let dnum_test_run_a = 0;
            let dnum_test_close_a = 0;
            let dnum_ok_a = 0;
            let dnum_stock_a = 0;

            let dnum_test_b = 0;
            let dnum_test_open_b = 0;
            let dnum_test_run_b = 0;
            let dnum_test_close_b = 0;
            let dnum_ok_b = 0;
            let dnum_stock_b = 0;

            const ret = [];

            const collect = (d, stock, k) => {
                const t_dnum = obj_int(d, k);
                const t_tech = obj_str_trim(d, "tech");
                const t_ball = obj_str_trim(d, "ball");

                const face = obj_str(d, "face");

                if (t_ball !== ball || t_tech !== tech || t_dnum <= 0) {
                    return;
                }

                if (stock === "test") {
                    const st = obj_str(d, "state");
                    if (st === "open") {
                        dnum_test_open += t_dnum;

                        if (face === "A") {
                            dnum_test_open_a += t_dnum;
                        } else if (face === "B") {
                            dnum_test_open_b += t_dnum;
                        }
                    } else if (st === "run") {
                        dnum_test_run += t_dnum;

                        if (face === "A") {
                            dnum_test_run_a += t_dnum;
                        } else if (face === "B") {
                            dnum_test_run_b += t_dnum;
                        }
                    } else {
                        dnum_test_close += t_dnum;

                        if (face === "A") {
                            dnum_test_close_a += t_dnum;
                        } else if (face === "B") {
                            dnum_test_close_b += t_dnum;
                        }
                    }

                    if (face === "A") {
                        dnum_test_a += t_dnum;
                    } else if (face === "B") {
                        dnum_test_b += t_dnum;
                    }

                    dnum_test += t_dnum;
                    d["stock"] = loc("l_796");
                    d["dnum"] = t_dnum;
                } else if (stock === "ok") {
                    dnum_ok += t_dnum;

                    d["stock"] = loc("l_795");
                    d["dnum"] = t_dnum;

                    if (face === "A") {
                        dnum_ok_a += t_dnum;
                    } else if (face === "B") {
                        dnum_ok_b += t_dnum;
                    }

                } else if (stock === "stock") {
                    dnum_stock += t_dnum;
                    d["stock"] = loc("l_797");

                    if (face === "A") {
                        dnum_stock_a += t_dnum;
                    } else if (face === "B") {
                        dnum_stock_b += t_dnum;
                    }
                }

                ret.push(d);
            };

            if (test) {
                test.forEach(d => collect(d, "test", "num"));
            }

            if (ok) {
                ok.forEach(d => collect(d, "ok", "num"));
            }

            if (stock) {
                stock.forEach(d => collect(d, "stock", "dnum"));
            }

            d_sort(ret, "tech");

            ret.forEach((d, i) => d["index"] = i + 1);

            setRow(ret);

            setSum([
                { index: loc("l_595"), stock: dnum_test + dnum_ok + dnum_stock,
                    da: dnum_test_a + dnum_ok_a + dnum_stock_a, db: dnum_test_b + dnum_ok_b + dnum_stock_b },
                { index: `${loc("l_796")}${loc("l_595")}`, stock: dnum_test, da: dnum_test_a, db: dnum_test_b },
                { index: `${loc("l_796")}${loc("l_301")}`, stock: dnum_test_open, da: dnum_test_open_a, db: dnum_test_open_b },
                { index: `${loc("l_796")}${loc("l_300")}`, stock: dnum_test_run, da: dnum_test_run_a, db: dnum_test_run_b},
                { index: `${loc("l_796")}${loc("l_302")}`, stock: dnum_test_close, da: dnum_test_close_a, db: dnum_test_close_b },
                { index: `${loc("l_795")}${loc("l_595")}`, stock: dnum_ok, da: dnum_ok_a, db: dnum_ok_b },
                { index: `${loc("l_797")}${loc("l_595")}`, stock: dnum_stock, da: dnum_stock_a, db: dnum_stock_b },
            ]);

            umd.endWait();
        };

        const calcStock = (test, ok) => {
            uDb(null, `${mod}/list`, { line: cline() },
                r => calc(test, ok, r),
                e => calc(test, ok, null));
        };

        const calcOk = (test) => uDb(null, `file/list/qa${mod}`, { line: cline() },
            r => calcStock(test, r),
            e => calcStock(test, null));

        uDb(null, `file/list/test${mod}`, { line: cline() },
            r => calcOk(r),
            e => calcOk(null));
    };

    const getCol = () => {
        const tmp = [
            {name: loc("l_193"), key: 'index', width: 120, frozen: true, summaryFormatter: ({ row }) => <strong>{obj_str(row, "index")}</strong>},
            {name: loc("l_794"), key: 'stock', width: 120, frozen: true, summaryFormatter: ({ row }) => <strong>{obj_str(row, "stock")}</strong>},
            {name: loc("l_127"), key: 'dnum', width: 120},
        ];

        get_col(col, tmp, map_supply, map_stuff, map_ng, true);

        if (mod === "seal" && tmp.length > 4) {
            tmp[2]["summaryFormatter"] = ({ row }) => <strong>{`B${loc("l_814")}`}<span className="ml-4">{obj_str(row, "db")}</span></strong>;
            tmp[3]["summaryFormatter"] = ({ row }) => <strong>{`A${loc("l_814")}`}<span className="ml-4">{obj_str(row, "da")}</span></strong>;
        }

        return tmp;
    };

    const hExport = () => {
        umd.startWait();

        const col_cen = getCol();
        if (is_empty(col_cen) || is_empty(row)) {
            umd.setErr(loc("l_276"));
        }

        const col_c = [];
        const h = [];

        col_cen.forEach(d => {
            h.push({ value: d.name });
            col_c.push(d.key);
        });

        const out = [h];

        row.forEach(d => {
            const tmp = [];
            col_c.forEach(t => tmp.push({ value: obj_str(d, t) }));

            out.push(tmp);
        });

        if (!is_empty(sum)) {
            out.push([{ value: "" }]);

            sum.forEach(d => {
                out.push([
                    { value: d["index"] },
                    { value: d["stock"] },
                ]);
            });
        }

        save_xlsx(out, `${title}_${loc("l_793")}_${form.get("tech")}.xlsx`, umd);
    };

    const Right = () => (
        <div className="inline-flex">
            <Btn hcmd={hExport} className="mr-4">{loc("l_519")}</Btn>
            <Ret hcmd={hreturn}/>
        </div>
    );

    return (
        <MainView>
            <PanelTitle left={<Title mod={loc("l_793")} sub={title}/>} right={<Right/>} cl="gray">
                <div className="flex items-center mb-1 justify-between">
                    <div className="inline-flex">
                        <Btn hcmd={() => hfind()} color="green" className="mr-4">{loc("l_332")}</Btn>
                        <KFind label={loc("l_363")} form={form} name="tech" margin="dense" width="w-56" list={techList}/>
                        <KFind label={loc("l_714")} form={form} name="ball" margin="dense" width="w-56" list={lst_ball} className="ml-4"/>
                    </div>
                </div>
            </PanelTitle>
            <GridTable col={getCol()} row={row} high={high} sumrow={sum}/>
            <WaitUmd umd={umd}/>
        </MainView>
    );
};

export {Census};
